package sketch;

import sketch.util.Checker;
import sketch.util.Globals;
import sketch.util.ReflectionExecutionOutcome;

public class BatchExecution {
	
	public final ReflectionExecutionOutcome[] outcomes;
	
	public final ExecutableSequenceContent[] contents;
	
	public final int expectedlength;
	
	public BatchExecution(ExecutableSequenceContent[] contents, ReflectionExecutionOutcome[] outcomes) {
		Checker.checkNull(contents, "The execution content could not be null!");
		Checker.checkNull(outcomes, "The method execution outcome could not be null!");
		this.expectedlength = contents.length;
		this.contents = contents;
		this.outcomes = outcomes;
	}
	
	public Object[] getExecutionResults() {
		int executedLength = this.getExecutedLength();
		Object[] results = new Object[executedLength];
		for(int i = 0; i < executedLength; i++) {
			results[i] = this.outcomes[i].getReturnObject();
		}
		return results;
	}
	
	public boolean hasAnyException() {
		//did not execute all the sequence
		if(getExecutedLength() != this.expectedlength) {
			return true;
		} else {
			ReflectionExecutionOutcome lastExe = this.outcomes[this.expectedlength -1];
			return lastExe.hasAnyException();
		}
	}
	
	public int getExecutedLength() {
		Checker.checkNull(outcomes, "Please set outcome first!");
		
		int index = 0;
		for(ReflectionExecutionOutcome outcome : this.outcomes) {
			Checker.checkNull(outcome, "The outcome is null, unexecuted?");
			if(outcome.hasAnyException()) {
				return index;
			}
			index++;
		}
		
		Checker.checkTrue(index == this.outcomes.length , "The index: " + index + " does not " +
				"equal to the outcome length: " + this.outcomes.length);
		
		return index;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("Expected execution length: " + this.expectedlength + ", has exception : " + this.hasAnyException()
				+ ",  execution length: " + this.getExecutedLength());
		sb.append(Globals.lineSep);
		for(ReflectionExecutionOutcome outcome : this.outcomes) {
			sb.append("  ");
			sb.append(outcome.toString());
			sb.append(Globals.lineSep);
		}
		
		return sb.toString();
	}
}
